package com.leyu.mall.service.user.impl;

/**
 * 
 */

import java.util.LinkedList;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.leyu.mall.common.util.Digests;
import com.leyu.mall.common.util.Encodes;
import com.leyu.mall.dao.user.RBACMapper;
import com.leyu.mall.dao.user.UserBaseMapper;
import com.leyu.mall.domain.user.Permision;
import com.leyu.mall.domain.user.Role;
import com.leyu.mall.domain.user.UserBase;
import com.leyu.mall.service.user.UserService;

/**
 * @author change
 * 
 */
@Service
public class UserServiceImpl implements UserService {
	public static final String HASH_ALGORITHM = "SHA-1";
	public static final int HASH_INTERATIONS = 1024;
	private static final int SALT_SIZE = 8;
	@Resource
	private UserBaseMapper userBaseMapper;
	@Resource
	private RBACMapper rbacMapper;

	@Override
	public boolean registerUser(UserBase user) {
		entryptPassword(user);
		userBaseMapper.insert(user);

		return user.getUserId() != null && user.getUserId() > 0;
	}

	/**
	 * 设定安全的密码，生成随机的salt并经过1024次 sha-1 hash
	 */
	private void entryptPassword(UserBase user) {
		byte[] salt = Digests.generateSalt(SALT_SIZE);
		user.setSalt(Encodes.encodeHex(salt));

		byte[] hashPassword = Digests.sha1(user.getPassword().getBytes(), salt,
				HASH_INTERATIONS);
		user.setPassword(Encodes.encodeHex(hashPassword));
	}

	private String toEntryptHex(String password, String salt) {
		byte[] hashPassword = Digests.sha1(password.getBytes(),
				Encodes.decodeHex(salt), HASH_INTERATIONS);
		return Encodes.encodeHex(hashPassword);
	}

	@Override
	public UserBase findByLoginName(String loginName) {
		UserBase userBase = userBaseMapper.findByUsername(loginName);
		if (userBase == null) {
			userBase = userBaseMapper.findByEmail(loginName);
		}
		return userBase;
	}

	@Override
	public boolean changePassword(String loginName, String oldPassword,
			String newPassword) {
		UserBase userBase = this.findByLoginName(loginName);
		if (userBase == null) {
			return false;
		}
		String oldPwdHex = this.toEntryptHex(oldPassword, userBase.getSalt());
		if (!oldPwdHex.equals(userBase.getPassword())) {
			return false;
		}
		int count = userBaseMapper.changePassword(loginName, oldPassword,
				newPassword);
		return count > 0;
	}

	@Override
	public List<Role> getUserRoles(Long userId) {
		return rbacMapper.listUserRoles(userId);
	}

	@Override
	public List<Permision> getPermisionsByRole(Long roleId) {
		return rbacMapper.listRolePermisions(roleId);
	}

	@Override
	public List<Permision> getPermisionsByUser(Long userId) {
		List<Role> roles = this.getUserRoles(userId);
		if (roles == null || roles.isEmpty()) {
			return null;
		}
		List<Long> idList = new LinkedList<Long>();
		for (Role role : roles) {
			idList.add(role.getId());
		}
		return rbacMapper.listRolePermisions(idList.toArray(new Long[] {}));
	}

}
